package com.ys.service.business.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ys.enume.base.TransactionTypeEnum;
import com.ys.enume.finance.TcwOperateFrozenRunningEnum;
import com.ys.util.DateUtil;
import com.ys.vo.W;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.alibaba.fastjson.JSON;
import com.ys.dto.AddDto;
import com.ys.entity.business.TpProductActive;
import com.ys.entity.business.TpProductActiveSq;
import com.ys.entity.finance.TcwAccountCountForCompany;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.business.TpProductActiveMapper;
import com.ys.mapper.business.TpProductActiveSqMapper;
import com.ys.service.business.TcwAccountDetailedForCompanyService;
import com.ys.service.business.TpProductActiveSqService;
import com.ys.service.finance.TcwAccountCountForCompanyService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tpProductActiveSqService")
public class TpProductActiveSqServiceImpl implements TpProductActiveSqService {

    @Autowired
    private TpProductActiveSqMapper tpProductActiveSqMapper;

    @Autowired
    private TpProductActiveMapper tpProductActiveMapper;

    public static Long MENU_ID = 10178L;

    @Autowired
    private YspTaskService yspTaskService;

    @Autowired
    private TcwAccountDetailedForCompanyService tcwAccountDetailedForCompanyService;
    @Autowired
    private TcwAccountCountForCompanyService tcwAccountCountForCompanyService;




    /**
     * 申请新增
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R add(Map<String, Object> params, String subData) throws Exception {
        // 验证订单号
        if (new TpProductActiveSq().setBid(params.get("bid").toString()).count() > 0) {
            return R.error("该申请单号已存在");
        }
        if (!params.get("fprice").toString().matches("\\d+(\\.\\d{0,2})?")){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式需要是数值，两位小数点！");
        }
//        // 验证是否有详情数据
//        JSONArray detailJA = JSON.parseArray(subData);
//        if (detailJA == null || detailJA.size() == 0) {
//            return R.error("详情数据不能为空");
//        }
        String loginUserId = ShiroUtils.getUserId();
        TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
        TpProductActiveSq tpProductActiveSq = new TpProductActiveSq();
        tpProductActiveSq.setBid(params.get("bid").toString());
        tpProductActiveSq.setVgsBm(params.get("vgsBm").toString());
        tpProductActiveSq.setListingId(Long.valueOf(params.get("listingId").toString()));
        tpProductActiveSq.setCode(params.get("code").toString());
        tpProductActiveSq.setName(params.get("name").toString());
        tpProductActiveSq.setCodeMerge(params.get("codeMerge").toString());
        tpProductActiveSq.setFprice(new BigDecimal(params.get("fprice").toString()));
        tpProductActiveSq.setVtitle(params.get("vtitle").toString());
        tpProductActiveSq.setVspLm1(params.get("vspLm1").toString());
        tpProductActiveSq.setVspGjz(params.get("vspGjz").toString());
        tpProductActiveSq.setVspMd1(params.get("vspMd1").toString());
        tpProductActiveSq.setVspMd2(params.get("vspMd2").toString());
        tpProductActiveSq.setVspMd3(params.get("vspMd3").toString());
        tpProductActiveSq.setVspMd4(params.get("vspMd4").toString());
        tpProductActiveSq.setVspMd5(params.get("vspMd5").toString());
        tpProductActiveSq.setVspZt(params.get("vspZt").toString());
        tpProductActiveSq.setVspZt1(params.get("vspZt1").toString());
        tpProductActiveSq.setVspCct(params.get("vspCct").toString());
        tpProductActiveSq.setVspXjt1(params.get("vspXjt1").toString());
        tpProductActiveSq.setVspXjt2(params.get("vspXjt2").toString());
        tpProductActiveSq.setVspXjt3(params.get("vspXjt3").toString());
        tpProductActiveSq.setVspCjt1(params.get("vspCjt1").toString());
        tpProductActiveSq.setVspCjt2(params.get("vspCjt2").toString());
        tpProductActiveSq.setVspCjt3(params.get("vspCjt3").toString());
        tpProductActiveSq.setCreateChangeId(String.valueOf(tsUserChange.getId()));
        tpProductActiveSq.setEffectStock(FlowEnum.EffectStock.NOT_EFFECT.value);
        tpProductActiveSq.setStatus(0);
        tpProductActiveSqMapper.insert(tpProductActiveSq);
        YsMenu ysMenu = new YsMenu().setId(MENU_ID).queryFirst();
        if (ysMenu.getFlowModelId().longValue() != 0L) {
            YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
            String codeModel = yspModel.getCode();
            String createUserId = ShiroUtils.getUserId();
            yspTaskService.init(codeModel, tpProductActiveSq.getBid(), createUserId);
        }
        return R.ok(AddDto.gotoEdit("/web/business/tpProductActiveSq/toEdit?id=" + tpProductActiveSq.getId()));
    }


    /**
     * 修改
     * @param params
     * @param subData
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R update(Map<String, Object> params, String subData) throws Exception {
        TpProductActiveSq tpProductActiveSq = JSON.parseObject(JSON.toJSONString(params), TpProductActiveSq.class);

        //判断是否实在制单中
        Integer flowState = yspTaskService.flowState(tpProductActiveSq.getBid());

        if (flowState != 0){
            return R.error("申请单不是制单中,不允许保存!");
        }

        //参数判断
        if (!params.get("fprice").toString().matches("\\d+(\\.\\d{0,2})?")){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式需要是数值，两位小数点！");
        }else if (params.get("fprice").toString().length() > 15){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务费格式长度不能大于15");
        }

        tpProductActiveSq.setVgsBm(params.get("vgsBm").toString());
        tpProductActiveSq.setListingId(Long.valueOf(params.get("listingId").toString()));
        tpProductActiveSq.setCode(params.get("code").toString());
        tpProductActiveSq.setName(params.get("name").toString());
        tpProductActiveSq.setCodeMerge(params.get("codeMerge").toString());
        tpProductActiveSq.setFprice(new BigDecimal(params.get("fprice").toString()));
        tpProductActiveSq.setVtitle(params.get("vtitle").toString());
        tpProductActiveSq.setVspLm1(params.get("vspLm1").toString());
        tpProductActiveSq.setVspGjz(params.get("vspGjz").toString());
        tpProductActiveSq.setVspMd1(params.get("vspMd1").toString());
        tpProductActiveSq.setVspMd2(params.get("vspMd2").toString());
        tpProductActiveSq.setVspMd3(params.get("vspMd3").toString());
        tpProductActiveSq.setVspMd4(params.get("vspMd4").toString());
        tpProductActiveSq.setVspMd5(params.get("vspMd5").toString());
        tpProductActiveSq.setVspZt(params.get("vspZt").toString());
        tpProductActiveSq.setVspZt1(params.get("vspZt1").toString());
        tpProductActiveSq.setVspCct(params.get("vspCct").toString());
        tpProductActiveSq.setVspXjt1(params.get("vspXjt1").toString());
        tpProductActiveSq.setVspXjt2(params.get("vspXjt2").toString());
        tpProductActiveSq.setVspXjt3(params.get("vspXjt3").toString());
        tpProductActiveSq.setVspCjt1(params.get("vspCjt1").toString());
        tpProductActiveSq.setVspCjt2(params.get("vspCjt2").toString());
        tpProductActiveSq.setVspCjt3(params.get("vspCjt3").toString());
        tpProductActiveSq.setUpdateTime(new Date());
        tpProductActiveSqMapper.update(tpProductActiveSq);
        return R.ok(AddDto.gotoEdit("/web/business/tpProductActiveSq/toEdit?id=" + tpProductActiveSq.getId()));
    }

    /**
     * 删除
     */
    @Override
    public R delete(Long id) {
        TpProductActiveSq tpProductActiveSq = new TpProductActiveSq().setId(id).queryFirst();
        if (tpProductActiveSq == null){
            R.error("申请不存在!");
        }
        tpProductActiveSqMapper.deleteTrue(id);
        return R.ok("删除成功!");
    }

    @Override
    public String checkParams(Map<String, Object> params, Long menuId) throws Exception {
        return null;
    }
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public R flowPass(Long id, String loginUserId) throws Exception {

        TpProductActiveSq entity = new TpProductActiveSq().setId(id).queryFirst();

        if (entity == null) {
            return R.error("该申请单不存在,请核实后再操作!");
        }
        String bid = entity.getBid();
        YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();

        // 若流程是初始化状态，需要验证账户金额
        if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
            //获取公司编码
            String vGsBm = entity.getVgsBm();
            //根据公司编码获取对应的实时资金表信息
            TcwAccountCountForCompany account = new TcwAccountCountForCompany().setVGsBm(vGsBm).queryFirst();
            //获取对应的实时资金信息
            BigDecimal amountAble = account.getFJe().add(account.getFFzEd()).subtract(account.getFDjJe());
            //判断金额是否大于公司的实时资金
            if (amountAble.compareTo(entity.getFprice().negate()) < 0) {
                return R.error("【" + vGsBm + "】账户可用余额不足，无法流转");
            }
        }
        try {
            Flow f = yspTaskService.flowPass(bid, loginUserId);
            if (f.getCode() == Flow.Code.FAILED.value) {
                return R.error(f.getMsg());
            } else {
                // 若是制单流转，冻结账户
                if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                    //获取公司编码
                    String vGsBm = entity.getVgsBm();
                    //获取要冻结的金额数
                    BigDecimal amount = entity.getFprice();
                    //冻结
                    tcwAccountCountForCompanyService.frozen(vGsBm, amount,
                            TcwOperateFrozenRunningEnum.DocumentType.TP_ProductActiveSq.value,
                            entity.getId(),
                            entity.getBid(),
                            null);
                }

                //若是制单完成
                if (f.getState() == Flow.State.FINISH.value) {
                    flowFinish(entity);
                }

                return R.ok();
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("服务器正在开小差，请联系客服");
        }
    }

    @Override
    public R flowRefuse(Long id, String reason, String loginUserId) throws Exception {

        TpProductActiveSq entity = new TpProductActiveSq().setId(id).queryFirst();
        String bid = entity.getBid();

        R r = yspTaskService.flowRefuse(bid, reason, loginUserId);

        if (r.getCode() == R.Code.SUCCESS.value) {
            YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
            // 若退回到制单状态，则解冻账户
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                //获取公司编码
                String vGsBm = entity.getVgsBm();
                //获取要解冻的金额数
                BigDecimal amount = entity.getFprice();
                //解冻
                tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                        TcwOperateFrozenRunningEnum.DocumentType.TP_ProductActiveSq.value,
                        entity.getId(),
                        entity.getBid(),
                        null);
            }

        }
        return r;
    }



    @Override
    public R flowInit(Long id, String reason, String loginUserId) throws Exception {

        TpProductActiveSq entity = new TpProductActiveSq().setId(id).queryFirst();
        String bid = entity.getBid();

        R r = yspTaskService.flowInit(bid, reason, loginUserId);

        if (r.getCode() == R.Code.SUCCESS.value) {
            YsProcInst ysProcInst = new YsProcInst().setBid(bid).queryFirst();
            // 若退回到制单状态，则解冻账户
            if (ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
                //获取公司编码
                String vGsBm = entity.getVgsBm();
                //获取要解冻的金额数
                BigDecimal amount = entity.getFprice();
                //解冻
                tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                        TcwOperateFrozenRunningEnum.DocumentType.TP_ProductActiveSq.value,
                        entity.getId(),
                        entity.getBid(),
                        null);
            }

        }
        return r;
    }

    public R flowFinish(TpProductActiveSq entity) throws Exception {
        Date date = new Date();
        entity.setEffectStock(1);
        entity.setUpdateTime(date);
        tpProductActiveSqMapper.update(entity);

        //查询产品运营公司
        Map<String, Object> thrOperateCompanyApply = new ThrOperateCompanyApply()
                .addLeftJoin("TS_AccountBandDept t2 on t2.VGsBm = A.VGsBm")
                .where("t2.AccountId = 'CPKF'")
                .queryFirstMap();
        if (thrOperateCompanyApply == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return R.error("产品运营公司不存在,核实后再操作!");
        }

        //划出流水
        tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompany(
                entity.getVgsBm(), thrOperateCompanyApply.get("vgsbm").toString(), TransactionTypeEnum.BusinessType.TP_AplusSq.name, entity.getFprice().negate(),
                date, date, "Listing申请:" + entity.getBid() + "，商品编码:" + entity.getCode(),
                entity.getBid(), null);

        //划入流水
        tcwAccountDetailedForCompanyService.addTcwAccountDetailedForCompany(
                thrOperateCompanyApply.get("vgsbm").toString(), entity.getVgsBm(), TransactionTypeEnum.BusinessType.TP_AplusSq.name, entity.getFprice(),
                date, date, "Listing申请:" + entity.getBid() + "，商品编码:" + entity.getCode(),
                entity.getBid(),null);
        TpProductActive tpProductActive=new TpProductActive().setId(entity.getListingId()).queryFirst();
        tpProductActive.setCode(entity.getCode());
        tpProductActive.setName(entity.getName());
        tpProductActive.setCode(entity.getCode());
        //tpProductActive.setVSpLm1(entity.getVspLm1());
        tpProductActive.setVspZt(entity.getVspZt());
        tpProductActive.setVspZt1(entity.getVspZt1());
        tpProductActive.setVspMd1(entity.getVspMd1());
        tpProductActive.setVspMd2(entity.getVspMd2());
        tpProductActive.setVspMd3(entity.getVspMd3());
        tpProductActive.setVspMd4(entity.getVspMd4());
        tpProductActive.setVspMd5(entity.getVspMd5());
        tpProductActive.setVspGjz(entity.getVspGjz());
        tpProductActive.setVspMd1(entity.getVspMd1());
        tpProductActive.setVspMd1(entity.getVspMd1());
        tpProductActive.setVspZt(entity.getVspZt());
        tpProductActive.setVspXjt3(entity.getVspXjt3());
        tpProductActive.setVspXjt2(entity.getVspXjt2());
        tpProductActive.setVspXjt1(entity.getVspXjt1());
        tpProductActive.setVspCct(entity.getVspCct());
        tpProductActive.setVspCjt1(entity.getVspCjt1());
        tpProductActive.setVspCjt2(entity.getVspCjt2());
        tpProductActive.setVspCjt3(entity.getVspCjt3());
        tpProductActive.setCodeMerge(entity.getCodeMerge());
        tpProductActive.setVtitle(entity.getVtitle());
        tpProductActive.setUpdateTime(new Date());
        //获取公司编码
        String vGsBm = entity.getVgsBm();
        //获取要解冻的金额数
        BigDecimal amount = entity.getFprice();
        //解冻
        tcwAccountCountForCompanyService.thaw(vGsBm, amount,
                TcwOperateFrozenRunningEnum.DocumentType.TP_ProductActiveSq.value,
                entity.getId(),
                entity.getBid(),
                null);
        tpProductActiveMapper.update(tpProductActive);
        return R.ok();
    }


    //获取列表数据
    @Override
    @Transactional
    public Map<String,Object> getExtraParam( String bid) throws Exception{
        Map<String, Object> extraParams = new TpProductActiveSq().setBid(bid)
                .addLeftJoin("THR_OperateCompanyApply THRO ON  THRO.VGsBm = A.VgsBm")
                .addField("THRO.VGsMc AS vgsMc,THRO.VGsJc AS vgsJc")
                .addLeftJoin("TP_ProductActive E ON  E.VgsBm = A.VgsBm")
                .queryFirstMap();

        YsProcInst ysProcInst = new YsProcInst().setBid(String.valueOf(extraParams.get("bid"))).queryFirst();
        extraParams.put("updateTime1", DateUtil.getYYYY_MM_DD_HH_mm_ss(ysProcInst.getUpdateTime()));
        extraParams.put("vgsJc", extraParams.get("vgsJc").toString());
        extraParams.put("vgsMc", extraParams.get("vgsMc").toString());
        return extraParams;
    }
}

